#!/usr/bin/env python
# coding=utf-8

from xml.dom import minidom, Node
import urllib2, HTMLParser
import os, sys, re

class MyHTMLParser(HTMLParser.HTMLParser):
    """my HTMLParser class"""
    def __init__(self):
        """init"""
        HTMLParser.HTMLParser.__init__(self)
        # if it has next page, it will be the URL of next page
        self.go_next = ""
        self.links = []
        self.link = ""
        # mark if found the target p tage
        self.found = 0
        # start to download the pictures
        self.download = 0
        # confirm to receive data
        self.receive_data = 0
        # the data that will be receive
        self.word = ""
        # tmp data
        self.tmp = ""

    def handle_starttag(self, tags, attrs):
        """if HTMLParser find an open tag, will do this function"""
        if not self.download:
            if tags == 'div':
                for attr in attrs:
                    if attr[0] == 'class' and attr[1] == 'imagethumb':
                        # find the photo link
                        self.found = 1
            if tags == 'a':
                # if the tag is <a>, jot it down
                for attr in attrs:
                    # find the href
                    if attr[0] == 'href':
                        # save the href value first
                        self.tmp = attr[1]
                        if self.found:
                            # if it is the target url, save it
                            self.links.append(self.tmp)
                    # find the next page link
                    elif (attr[0] == 'title' and attr[1] == 'Next Page'):
                        # if it is the Next Page url, save from the href value
                        self.go_next = self.tmp
        elif self.download:
            # if it is the final step, receive the data(Link name)
            if tags == 'strong':
                self.receive_data = 1
            if tags == 'img' and self.receive_data:
                for attr in attrs:
                    if attr[0] == 'src':
                        self.link = attr[1]

    def handle_data(self, data):
        """records the incoming data inside a tag"""
        # save the data to word, it should be the Link name
        if self.receive_data:
            self.word += data

    def handle_endtag(self, tag):
        if not self.download and tag == 'div':
            # if it is tag </p>, close it
            self.found = 0
        if self.download and tag == 'strong':
            # if it is the final step, and the tag is </a>
            # search the Link name, if it is the Download link save the link
            #if self.word.count("Download"):
                #self.link = self.tmp
            # close the tag
            self.receive_data = 0
            self.word = ""

class main:
    """main class"""
    def __init__(self, url):
        # last processing url
        self.page_url = ""
        self.link_list = []
        self.img_list = []
        # the url of next page
        self.next_page = ""
        # total images that downloaded
        self.total = 0
        # while searching photos
        self.searching = 1
        # downloading which photo
        self.downloading = 0
        print "Program Start"
        self.getPage(url)
        print "Search all pictures' links Finished!!"
        self.getPic(self.link_list)

    def getPic(self, link_list):
        """get the Pictures from Flickr"""
        img = "http://www.flickr.com/photo_zoom.gne?id=%s&size=l"
        for i in link_list:
            for j in i:
                # get the id from url
                id = j.split('/')[-2]
                # join the id to the image link
                #data = self.goLink(img % id)
                data = self.goLink(j)
                if (data):
                    # go to the final step
                    parser = MyHTMLParser()
                    parser.download = 1
                    parser.feed(data)
                    self.img_list.append(parser.link)
        print "Start Download Pictures"
        for i in self.img_list:
            self.downloading += 1
            #print i
            self.downLink(i)

    def getPage(self, url):
        """get the Flickr HTML Page"""
        # get the data
        data = self.goLink(url)
        if ( data ):
            # creat the HTML Parser
            parser = MyHTMLParser()
            # get the information
            parser.feed(data)
            #print parser.result()
            self.link_list.append(parser.links)
            self.total += len(parser.links)
            while (parser.go_next):
                print "Next: %s" % parser.go_next
                data = self.goLink(parser.go_next)
                if data:
                    parser = MyHTMLParser()
                    parser.feed(data)
                    #print parser.result()
                    self.link_list.append(parser.links)
                    self.total += len(parser.links)

    def getPageDOM(self, url):
        """get the Flickr HTML Page information using DOM"""
        # get the dtat first
        data = self.goLink(url)
        doc = minidom.parseString(data)
        for child in doc.childNodes:
            if child.nodeType == Node.ELEMENT_NODE and child.tagName == 'body':
                # get the body, tree root
                self.handle(child)

    def handle(self, node):
        """get the information from child"""
        for child in node.childNodes:
            # check it is element node
            if child.nodeType == Node.ELEMENT_NODE:
                # get the next page link
                if child.tagName == 'a':
                    if child.getAttribute('class') == 'Next':
                        self.next_page = child.getAttribute('href')

    def downLink(self, input_url):
        """down a file from url"""
        # check the url
        if input_url.startswith('http'):
            # this is an absolute url
            url = input_url
        elif input_url.startswith('/'):
            # it is a relative url, but relate to the root
            a = self.page_url.split('/')
            url = a[0] + '//' + a[2] + input_url
        else:
            # it is a relative url also, but relate to "this page"
            a = self.page_url.rfind('/')
            url = self.page_url[0:a] + input_url
        print "Download this: ", url
        request = urllib2.Request(url)
        img = urllib2.urlopen(request)
        file_name = img.geturl().split('/')[-1]
        file = open(file_name, "wb")
        print >> file, img.read()
        file.close()
        img.close()

    def goLink(self, input_url):
        """open a url, and return the data"""
        # check the url
        if ( input_url.startswith('http') ):
            url = input_url
        elif ( input_url.startswith('/') ):
            a = self.page_url.split('/')
            url = a[0] + '//' + a[2] + input_url
        else:
            a = self.page_url.rfind('/')
            url = self.page_url[0:a] + input_url
        print "Open URL: %s" % url
        print "Loading........."
        # creat a request
        request = urllib2.Request(url)
        # open the url
        html_p = urllib2.urlopen(request)
        # get the html page data from http server
        data = html_p.read()
        html_p.close()
        # return the data
        print "download page successful"
        self.page_url = html_p.geturl()
        return data


if __name__ == "__main__":
    if (len(sys.argv) == 2):
        main(sys.argv[1])
